#pragma once

#include <pthread.h>
#include <functional>
#include "log.hpp"
#include "Sock.hpp"
#include "Protocol.hpp"

using namespace std;
using func_t = function<Response(const Request&)>;
class TcpServer; //前置声明

//线程数据
class ThreadDate
{
public:
    ThreadDate(int sock, const string& ip, uint16_t port, TcpServer* tser): _sock(sock), _ip(ip), _port(port), _tser(tser)
    {}
    ~ThreadDate()
    {}
public:
    int _sock;
    string _ip;
    uint16_t _port;
    TcpServer* _tser; 
};

static uint16_t default_port = 8080;

//服务端
class TcpServer
{
public:
    TcpServer(func_t func, uint16_t port = default_port):_func(func), _port(port)
    {}

    void Init()
    {
        _listen_sock.Socket();
        _listen_sock.Bind(_port);
        _listen_sock.Listen();

        log_message(Info, "init success, _listen_sock: %d", _listen_sock.GetSock());
    }

    void Start()
    {
        while(true)
        {
            string client_ip;
            uint16_t client_port;
            int sock = _listen_sock.Accept(client_ip, client_port);
            if(sock < 0)
            {
                continue;
            }

            log_message(Debug, "accept success, client_ip: %s, client_port: %d", client_ip.c_str(), client_port);
            pthread_t tid;
            ThreadDate* td = new ThreadDate(sock, client_ip, client_port, this);
            pthread_create(&tid, nullptr, ThreadRoutine, td);
        }
        
    }

    static void* ThreadRoutine(void* args)
    {
        pthread_detach(pthread_self());
        ThreadDate* td = static_cast<ThreadDate*>(args);

        td->_tser->ServiceIO(td->_sock, td->_ip, td->_port);
        delete td;
        return nullptr;
    }

    void ServiceIO(int sock, const string& client_ip, const uint16_t& client_port)
    {
        string inbuffer;
        while(true)
        {   
            string package;
            int n = ReadPackage(sock, inbuffer, package);
            //1:读取失败
            //2:有效荷载的长度都没有读取到
            //3:读取到了有效荷载的长度,但是并没有读取完全有效荷载
            if(n == -1)
            {
                break;
            }
            else if(n == 0)
            {
                continue;
            }
            else
            {      
                string effective_data = SubHeaders(package, n); //将读取到的数据去掉报头

                //将序列化的请求反序列化
                Request req;
                req.Deserialize(effective_data);
                //scout << req._x << req._op << req._y << endl;

                Response res = _func(req); //业务处理
                 
                //序列化后返回给用户
                string send_msg;
                res.Serialize(send_msg);
                
                //加报头
                send_msg = AddHeaders(send_msg);

                //发送回用户
                send(sock, send_msg.c_str(), send_msg.size(), 0);
            }  
        }
        close(sock);
    }

    ~TcpServer()
    {

    }
private:
    func_t _func;
    uint16_t _port;
    Sock _listen_sock;
};